package io.ede.modules.ede.controller;

import io.ede.common.exception.RRException;
import io.ede.common.utils.*;
import io.ede.common.validator.ValidatorUtils;
import io.ede.modules.ede.entity.GroupEntity;
import io.ede.modules.ede.entity.ProjectEntity;
import io.ede.modules.ede.service.GroupService;
import io.ede.modules.ede.service.ModelService;
import io.ede.modules.ede.service.ProjectService;
import io.ede.modules.oss.cloud.OSSFactory;
import io.ede.modules.oss.entity.SysOssEntity;
import io.ede.modules.oss.service.SysOssService;
import io.ede.modules.sys.entity.SysUserEntity;
import io.ede.modules.sys.shiro.ShiroUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;


/**
 * @author Mark
 * @email sunlightcs@gmail.com
 * @date 2019-08-27 13:28:09
 */
@RestController
@RequestMapping("ede/project")
public class ProjectController {
    @Autowired
    private ProjectService projectService;
    @Autowired
    private GroupService groupService;
    @Autowired
    private ModelService modelService;
    @Autowired
    private SysOssService sysOssService;

    @Value("${project.path}")
    public String path;

    /**
     * 导出工程
     * @param params
     * @return
     */
    @RequestMapping("/export")
    public void exportProject(@RequestParam Map<String, Object> params,HttpServletResponse res) {
        String id = (String) params.get("id");
        ProjectEntity project = projectService.getById(id);
        SysUserEntity userEntity = ShiroUtils.getUserEntity();
        if (project != null) {
            String filePath = path + "/" + userEntity.getUserId() + "/" + project.getProject() + "/" + project.getProject();
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            //生成fii文件
            String fii = filePath + "/" + project.getProject() + ".fii";
            FileUtils.writeFile(fii, project.getFii());
            //生成动作组
            Map<String, Object> map = new HashMap<>();
            map.put("project_id", project.getId());
            map.put("del_flag", "1");
            List<GroupEntity> list = (List<GroupEntity>) groupService.listByMap(map);
            String groupSumPath = filePath + "/" + "动作组";
            File groupSumFile = new File(groupSumPath);
            if (!groupSumFile.exists()) {
                groupSumFile.mkdirs();
            }
            for (GroupEntity group : list) {
                String groupPath = groupSumPath + "/" + group.getName();
                File groupFile = new File(groupPath);
                //创建动作组目录
                if (!groupFile.exists()) {
                    groupFile.mkdirs();
                }
                //创建动作组下的文件
                String py = group.getPy();
                String xml = group.getXml();
                String pyPath = groupSumPath + "/" + group.getName() + "/" + "webCodeAll.py";
                String xmlPath = groupSumPath + "/" + group.getName() + "/" + "webCodeAll.xml";
                FileUtils.writeFile(pyPath, py);
                FileUtils.writeFile(xmlPath, xml);
            }

            //下载音乐
            //todo
            //String netUrl = "http://img.qdmay.top/ede/20190912/bfba849ae667407da675a47d0281cd1c.mp3";
            String netUrl = project.getMusic();
            if(StringUtils.isNotBlank(netUrl)){
                String local = groupSumPath + "/" + project.getProject() + ".mp3";
                FileUtils.downLoadNetFile(netUrl, local);
            }

            //打包工程
            String sourse = path + "/" + userEntity.getUserId() + "/" + project.getProject();
            String dept = path + "/" + userEntity.getUserId() + "/" + project.getProject() + ".zip";
            ZipUtils.zipFiles(sourse, dept);

            //下载文件
            FileInputStream is = null;
            BufferedInputStream bs = null;
            OutputStream os = null;

            try {
                InputStream inputData = new FileInputStream(dept);
                res.setContentType("application/octet-stream");
                res.setHeader("Content-Disposition", "attachment;filename=" + new String((project.getProject() + ".zip").getBytes("gb2312"), "ISO8859-1"));
                bs = new BufferedInputStream(inputData);
                os = res.getOutputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = bs.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                    if (bs != null) {
                        bs.close();
                    }
                    if (os != null) {
                        os.flush();
                        os.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 导入工程
     *
     * @return
     */
    @RequestMapping("/upload")
    public R importProject(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }

        //上传文件
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if (!(".zip".equals(suffix) || ".rar".equals(suffix))) {
            throw new RRException("文件格式不正确，只能是zip或者rar");
        }

        //读取解压包内容
        //InputStream in = file.getInputStream();
        boolean flag = projectService.importPorject(file,suffix);
        if (flag) {
            return R.ok("导入成功！");
        } else {
            return R.error("导入失败！");
        }
    }

    /**
     * 上传音乐
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadMusic")
    public R uploadMusic(@RequestParam("file") MultipartFile file,@RequestParam("id") String id) throws Exception {
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }

        //上传文件
        String musicName = file.getOriginalFilename();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);

        //保存文件信息
        SysOssEntity ossEntity = new SysOssEntity();
        ossEntity.setUrl(url);
        ossEntity.setCreateDate(new Date());
        sysOssService.save(ossEntity);

        //String url = "http://img.qdmay.top/ede/20190912/bfba849ae667407da675a47d0281cd1c.mp3";

        //保存音乐路径
        ProjectEntity project = projectService.getById(id);
        project.setMusic(url);
        project.setMusicName(musicName.substring(musicName.lastIndexOf(File.separator)+1));
        //修改fii文件
        SAXReader reader = new SAXReader();
        Document document;
        try {
            String fii = project.getFii();
            document = reader.read(new ByteArrayInputStream(fii.getBytes("utf-8")));
            //获取root(根)节点
            Element root=document.getRootElement();
            //删除音乐节点
            XmlParser.deleteElement(root,"MusicName");
            //重新添加新音乐
            XmlParser.addElement(root,"MusicName", "path", project.getProject(), "");
            project.setFii(document.asXML());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //计算音乐空间大小
        project.setSpace(file.getBytes().length/1024);
        projectService.updateById(project);
        //重新计算用户空间
        projectService.updUserSpace();

        //return R.ok().put("url", url);
        return R.ok().put("project", project);

    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("ede:project:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = projectService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("ede:project:info")
    public R info(@PathVariable("id") Integer id) {
        ProjectEntity project = projectService.getById(id);
        if(project != null){
            project.setModelName(modelService.getById(project.getModelId()).getModel());
        }


        return R.ok().put("project", project);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody ProjectEntity project) {
        SysUserEntity userEntity = ShiroUtils.getUserEntity();
        project.setUserId(userEntity.getUserId().intValue());
        String[] areaArr = project.getAreaL().split("\\*");
        project.setAreaL(areaArr[0]);
        project.setAreaW(areaArr[1]);
        project.setCreateTime(new Date());
        String fii = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "   <GoertekGraphicXml>\n" +
                "       <DeviceType DeviceType=\"" + project.getModelName() + "\" />\n" +
                "       <Actions actionname=\"动作组1\" />\n" +
                "       <AreaL AreaL=\"" + areaArr[0] + "\" />\n" +
                "       <AreaW AreaW=\"" + areaArr[1] + "\" />\n" +
                "       <AreaH AreaH=\"300\" />\n" +
                "   </GoertekGraphicXml>";
        project.setFii(fii);
        projectService.save(project);
        return R.ok().put("project",project);
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //@RequiresPermissions("ede:project:update")
    public R update(@RequestBody ProjectEntity project) {
        ValidatorUtils.validateEntity(project);
        project.setUpdateTime(new Date());
        projectService.updateById(project);
        //重新计算工程
        projectService.updUserSpace();

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("ede:project:delete")
    public R delete(@RequestBody Integer[] ids) {
        projectService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    /**
     * 我的工程
     *
     * @return
     */
    @RequestMapping("/selectByMap")
    public R selectByMap() {
        SysUserEntity userEntity = ShiroUtils.getUserEntity();
        Long userId = userEntity.getUserId();
        Map<String, Object> params = new HashMap<>();
        params.put("user_id", userId);
        params.put("del_flag", "1");
        List<ProjectEntity> list = projectService.selectByMap(params);
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setModelName(modelService.getById(list.get(i).getModelId()).getModel());
        }

        return R.ok().put("list", list);
    }

    /**
     * 加载动作组
     *
     * @param params
     * @return
     */
    @RequestMapping("/selectActions")
    public R actions(@RequestParam Map<String, Object> params) {
        String id = (String) params.get("id");
        ProjectEntity project = projectService.getById(id);
        String fii = project.getFii();
        //获取动作组
        List<HashMap<String, Object>> actionList = FiiUtils.getFiiActions(fii);
        return R.ok().put("actionList", actionList);
    }

    /**
     * 保存工程
     *
     * @param
     * @return
     */
    @RequestMapping("/saveProject")
    public R saveProject(String projectId,String py,String xml,String name) {
        GroupEntity group = new GroupEntity();
        xml = URLDecoder.decode(xml);
        group.setProjectId(Integer.parseInt(projectId));
        group.setPy(py);
        group.setXml(xml);
        group.setName(name);
        projectService.saveProject(group);
        return R.ok().put("actionList", "");
    }


}
